perm filename PROGS.PAL[11,HE] blob
sn#666535 filedate 1982-07-09 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00009 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 Program to copy a disk image to & from the 10 DCOPY.PAL
C00015 00003 BOOT.PAL
C00016 00004 BOOT2.PAL
C00017 00005 Program to test out the DR11-C DR11C.PAL
C00025 00006 DZ11.PAL
C00027 00007 Program to talk to one of the PUMA's with the VT05 PUMA.PAL
C00031 00008 Program to test out communication with the Vision Module via the DR11-C
C00048 00009 Program to talk to the 10 with the VT05
C00052 ENDMK
C⊗;
;Program to copy a disk image to & from the 10 DCOPY.PAL
.INSRT STUFF.PAL[11,ARG]
BUF1 = 10000
BUF2 = 40000
.=1000
BUFPT: 0 ;Where the 10 will look for the disk buffer
DRVNUM: 0 ;Which disk drive we're to use
DOIT: 0 ;Set when drive number is valid
START: RESET
MOV #1000,SP ;Set up the stack
MOV #BEGMES,R1 ;Tell world who we are
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
CLR DOIT
LOOP: CLR BUFPT
1$: TST DOIT ;Wait until 10's ready
BEQ 1$
MOV DRVNUM,R0 ;Get desired drive #
BIC #177774,R0
ASH #13.,R0 ;Shift drive # to high order bits
2$: TSTB RKCS ;Make sure drive is ready
BPL 2$ ; Nope - keep waiting
MOV R0,RKDA ;Select drive, cyl 0, surface 0, sector 0
MOV DOIT,R0 ;See whether we're reading or writing
CLR DOIT
CMP #1,R0 ;Reading?
BEQ READ ; Yes
JMP WRITE ; No
READ: MOV RKDA,R2 ;Save Disk address register
MOV #BUF1,RKBA ;Fill up both buffers
MOV #-30000,RKWC ;Set word count
MOV #5,RKCS ;Go read in the first two cylinders
1$: TSTB RKCS ;Wait for disk operation to finished
BPL 1$ ; Nope - keep waiting
TST RKCS ;See that last operation didn't cause an error
BPL 2$ ; Skip ahead if everything's ok
MOV #1,BUFPT ;Tell 10 we had an error
MOV #ERRMES,R1 ;Complain about it too
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT ;Punt
2$: MOV #BUF1,RKBA ;Now let's confirm that the read was ok
MOV R2,RKDA ;Restore old disk address register
MOV #-30000,RKWC ;Set word count
MOV #13,RKCS ;Go read check the first two cylinders
3$: TSTB RKCS ;Wait for disk operation to finish
BPL 3$ ; Nope - keep waiting
MOV #201.,R5 ;# of cylinders more to read
MOV #BUF1,BUFPT ;Tell 10 data's ready for it now
RLOOP: TST BUFPT ;Wait til 10's done with buffer
BNE RLOOP
1$: TSTB RKCS ;See if last disk operation has finished
BPL 1$ ; Nope - wait
TST RKCS ;See that last operation didn't cause an error
BPL 3$ ; Skip ahead if everything's ok
2$: MOV #1,BUFPT ;Tell 10 we had an error
MOV #ERRMES,R1 ;Complain about it too
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT ;Punt
3$: MOV #BUF2,BUFPT ;Start 10 on 2nd buffer while we refill 1st
MOV #BUF1,R4
MOV R4,RKBA ;Filling up buffer 1
MOV RKDA,R2 ;Save Disk address register
MOV #-14000,RKWC ;Set word count
MOV #5,RKCS ;Go read in the next cylinder
4$: TSTB RKCS ;Wait for disk operation to finish
BPL 4$ ; Nope - keep waiting
TST RKCS ;See that last operation didn't cause an error
BMI 2$ ; Complain if it did
MOV #BUF1,RKBA ;Now let's confirm that the read was ok
MOV R2,RKDA ;Restore old disk address register
MOV #-14000,RKWC ;Set word count
MOV #13,RKCS ;Go read check the cylinder
DEC R5 ;Check if that's the last one
BEQ RLBUF ; & get ready to quit of so
RB2LP: TST BUFPT ;Wait til 10's done with second buffer
BNE RB2LP
1$: TSTB RKCS ;See if last disk operation has finished
BPL 1$ ; Nope - wait
TST RKCS ;See that last operation didn't cause an error
BPL 3$ ; Skip ahead if everything's ok
2$: MOV #1,BUFPT ;Tell 10 we had an error
MOV #ERRMES,R1 ;Complain about it too
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT ;Punt
3$: MOV #BUF1,BUFPT ;Start 10 on 1st buffer while we refill 2nd
MOV RKDA,R2 ;Save Disk address register
MOV #BUF2,R4
MOV R4,RKBA ;Filling up buffer 2
MOV #-14000,RKWC ;Set word count
MOV #5,RKCS ;Go read in the next cylinder
4$: TSTB RKCS ;Wait for disk operation to finish
BPL 4$ ; Nope - keep waiting
TST RKCS ;See that last operation didn't cause an error
BMI 2$ ; Complain if it did
MOV #BUF2,RKBA ;Now let's confirm that the read was ok
MOV R2,RKDA ;Restore old disk address register
MOV #-14000,RKWC ;Set word count
MOV #13,RKCS ;Go read check the cylinder
DEC R5 ;Check if more cylinders to be read
BNE RLOOP
RLBUF: TST BUFPT ;Wait til 10's done with previous buffer
BNE RLBUF
1$: TSTB RKCS ;See if disk operation has finished
BPL 1$ ; Nope - wait
TST RKCS ;See that last operation didn't cause an error
BPL 2$ ; Skip ahead if everything's ok
MOV #1,BUFPT ;Tell 10 we had an error
MOV #ERRMES,R1 ;Complain about it too
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT ;Punt
2$: MOV R4,BUFPT ;Start 10 on last buffer
3$: TST BUFPT ;Wait til 10's done with buffer
BNE 3$
JMP LOOP ;We're all done now
WRITE: MOV #BUF1,BUFPT ;Tell 10 to start filling buffer 1
MOV #203.,R5 ;# of cylinders we'll be writing
MOV #11,RKCS ;Do a seek operation to get ready
WLOOP: TST BUFPT ;Wait til 10's done with buffer
BNE WLOOP
1$: TSTB RKCS ;See if last disk operation has finished
BPL 1$ ; Nope - wait
TST RKCS ;See that last operation didn't cause an error
BPL 3$ ; Skip ahead if everything's ok
2$: MOV #1,BUFPT ;Tell 10 we had an error
MOV #ERRMES,R1 ;Complain about it too
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT ;Punt
3$: MOV #BUF2,BUFPT ;Start 10 on 2nd buffer while we empty 1st
MOV RKDA,R2 ;Save Disk address register
MOV #BUF1,RKBA ;Writing out buffer 1
MOV #-14000,RKWC ;Set word count
MOV #3,RKCS ;Go write out the next cylinder
4$: TSTB RKCS ;Wait for disk operation to finish
BPL 4$ ; Nope - keep waiting
TST RKCS ;See that last operation didn't cause an error
BMI 2$ ; Complain if it did
MOV #BUF1,RKBA ;Now let's confirm that the write was ok
MOV R2,RKDA ;Restore old disk address register
MOV #-14000,RKWC ;Set word count
MOV #7,RKCS ;Go write check the cylinder
DEC R5 ;Check if that's the last one
BEQ WLBUF ; Yup go quit
WB2LP: TST BUFPT ;Wait til 10's done with second buffer
BNE WB2LP
1$: TSTB RKCS ;See if last disk operation has finished
BPL 1$ ; Nope - wait
TST RKCS ;See that last operation didn't cause an error
BPL 3$ ; Skip ahead if everything's ok
2$: MOV #1,BUFPT ;Tell 10 we had an error
MOV #ERRMES,R1 ;Complain about it too
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT ;Punt
3$: MOV #BUF1,BUFPT ;Start 10 on 1st buffer while we empty 2nd
MOV RKDA,R2 ;Save Disk address register
MOV #BUF2,RKBA ;Writing out buffer 2
MOV #-14000,RKWC ;Set word count
MOV #3,RKCS ;Go write out the next cylinder
4$: TSTB RKCS ;Wait for disk operation to finish
BPL 4$ ; Nope - keep waiting
TST RKCS ;See that last operation didn't cause an error
BMI 3$ ; Complain if it did
MOV #BUF2,RKBA ;Now let's confirm that the write was ok
MOV R2,RKDA ;Restore old disk address register
MOV #-14000,RKWC ;Set word count
MOV #7,RKCS ;Go write check the cylinder
DEC R5 ;Check if that's the last one
BNE WLOOP ; Nope - keep going
WLBUF: TST BUFPT ;Wait til 10's done with previous buffer
BNE WLBUF
1$: TSTB RKCS ;Wait for disk operation to finish
BPL 1$ ; Nope - keep waiting
TST RKCS ;See that last operation didn't cause an error
BPL 2$ ; Skip ahead if everything's ok
MOV #1,BUFPT ;Tell 10 we had an error
MOV #ERRMES,R1 ;Complain about it too
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT ;Punt
2$: MOV #2,BUFPT ;Tell 10 last buffer was okay
3$: TST BUFPT ;Wait til 10's done with buffer
BNE 3$
JMP LOOP ;We're all done now
;VT05 I/O routines
OUTSTR: MOVB (R1)+,R0 ;Get next char
BEQ 1$ ;If done - quit
JSR PC,OUTCHR ;Print it
BR OUTSTR
1$: JSR PC,OUTCHR ;Print a couple nulls
JSR PC,OUTCHR
; JMP OUTCHR
OUTCHR: TST OUTSW ;Who does it go to?
BEQ 2$
1$: TSTB KBOS ;VT05 ready?
BPL 1$ ;Loop til it is
MOVB R0,KBOR ;Print the char
RTS PC
2$: TSTB OREG ;Console ready?
BNE 2$ ;Wait til it is
MOVB R0,OREG ;Output char
RTS PC
INCHR: TST OUTSW ;Where does it come from?
BEQ 1$
TSTB KBIS ;Anything typed on VT05?
BPL 2$ ; No
MOVB KBIR,R0 ; Read the char
RTS PC
1$: TSTB IREG ;Anything from the 10?
BEQ 2$ ; No
MOVB IREG,R0 ; Fetch the char
CLRB IREG
RTS PC
2$: CLR R0 ;No input
RTS PC
;Data & Constants
BEGMES: .ASCII /πDisk Copy Program/
CRLF: .BYTE 12,15,0
ERRMES: .ASCIZ /πDisk Errorπ/
.END START
; BOOT.PAL
.=1000
START: MOV #177406,%0 ;ADDR WORD COUNT REG
MOV #177400,(%0) ;READ 400 WDS
; MOV #40000,4(%0) ;USE DRIVE 2 (60000 FOR 3, 20000 FOR 1)
MOV #5,-(%0) ;GO READ
1$: TSTB (%0) ;WAIT TIL DONE
BPL 1$
CLR %7 ;JUMP TO BOOTSTRAP AT LOC 0
.END START
; BOOT2.PAL
.=1000
START: MOV #177406,%0 ;ADDR WORD COUNT REG
MOV #177400,(%0) ;READ 400 WDS
MOV #40000,4(%0) ;USE DRIVE 2 (60000 FOR 3, 20000 FOR 1)
MOV #5,-(%0) ;GO READ
1$: TSTB (%0) ;WAIT TIL DONE
BPL 1$
CLR %7 ;JUMP TO BOOTSTRAP AT LOC 0
.END START
;Program to test out the DR11-C DR11C.PAL
.INSRT STUFF.PAL[11,ARG]
;DR11-C definitions
DRCSR = 763770 ;Control and Status register
DROBUF = 763772 ;Output Buffer register
DRIBUF = 763774 ;Input Buffer register
DRIVEC = 340 ;Request A & B interrupt vectors
.=DRIVEC
DRINTA ;Req A interrupt handler
240 ;Level 5
DRINTB ;Req B interrupt handler
240 ;Level 5
.=1000
START: RESET
MOV #START,SP ;Set up the stack
MOV #BEGMES,R1 ;Tell world who we are
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
CLR %PS ;Priority level 0
MOV #DRINTA,DRIVEC ;Set up interrupt vectors
MOV #DRINTB,DRIVEC+4
MOV #140,DRCSR ;Enable interrupts
MOV #RAMES,R1 ;Ready to cause a Req A interrupt
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
CLR ADONE
BIS #1,DRCSR ;Set CSR0 = Req A
1$: TST ADONE
BEQ 1$ ;Wait around until interrupt handled
MOV #NOIMES,R1 ;Ready to not cause another one
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
CLR ADONE
MOV #100,R4
BIS #1,DRCSR ;Set CSR0 = Req A
2$: TST ADONE
BNE TB ;Was interrupt handled?
SOB R4,2$ ;Wait a little bit
TB: MOV #RBMES,R1 ;Ready to cause a Req B interrupt
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
CLR BDONE
BIS #2,DRCSR ;Set CSR1 = Req B
1$: TST BDONE
BEQ 1$ ;Wait around until interrupt handled
MOV #NOIMES,R1 ;Ready to not cause another one
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
CLR BDONE
MOV #100,R4
BIS #2,DRCSR ;Set CSR1 = Req B
2$: TST BDONE
BNE BOTH ;Was interrupt handled?
SOB R4,2$ ;Wait a little bit
BOTH: MOV #BIMES,R1 ;Ready to cause both
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
CLR BDONE
CLR ADONE
MOV #100,R4
BIC #3,DRCSR ;Get ready to interrupt both
BIS #3,DRCSR ;Set CSR0 & CSR1 = Req A & B
1$: MOV BDONE,R0
ADD ADONE,R0
CMP R0,#2
BGE SEND ;Both interrupts handled?
SOB R4,1$ ;Wait a little bit more if need be
SEND: MOV #SNDMES,R1 ;Ready to send a message
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
MOV #OBUF,OPTR ;Set up things for sending a message
MOV #10,OCNT
MOV #IBUF,IPTR
MOV #10,ICNT
MOV #RCVR,DRIVEC ;Set up interrupt vctors
MOV #SNDR,DRIVEC+4
CLR MDONE
BIC #3,DRCSR ;Clear old interrupts
BIS #2,DRCSR ;Start up the send routine
1$: TST MDONE
BEQ 1$ ;Wait for it to finish
MOV #RCVMES,R1 ;All done with it
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT
JMP START
;Various interrupt routines
DRINTA: CLR R0
1$: DEC R0
BNE 1$ ;Kill some time
MOV #AMES,R1 ;Tell world who we are
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
CLR R0
2$: DEC R0
BNE 2$ ;Kill some more time
INC ADONE
RTI ;All done here
DRINTB: CLR R0
1$: DEC R0
BNE 1$ ;Kill some time
MOV #BMES,R1 ;Tell world who we are
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
CLR R0
2$: DEC R0
BNE 2$ ;Kill some more time
INC BDONE
RTI ;All done here
;Now let's get serious
SNDR: BIC #3,DRCSR ;Turn off interrupts
DEC OCNT ;Any more?
BLT 1$ ; no
MOV @OPTR,DROBUF ;Get next word to send
ADD #2,OPTR
INC DRCSR ;Set CSR0 = Req A
1$: RTI
RCVR: BIC #3,DRCSR ;Turn off interrupts
DEC ICNT ;Any more?
BGT 1$ ; yes
INC MDONE ; no - indicate all done
BR 2$
1$: MOV DRIBUF,@IPTR ;Get next word
ADD #2,IPTR
BIS #2,DRCSR ;Ready for next - set CSR1 = Req B
2$: RTI
;VT05 I/O routines
OUTSTR: MOVB (R1)+,R0 ;Get next char
BEQ 1$ ;If done - quit
JSR PC,OUTCHR ;Print it
BR OUTSTR
1$: JSR PC,OUTCHR ;Print a couple nulls
JSR PC,OUTCHR
; JMP OUTCHR
OUTCHR: TST OUTSW ;Who does it go to?
BEQ 2$
1$: TSTB KBOS ;VT05 ready?
BPL 1$ ;Loop til it is
MOVB R0,KBOR ;Print the char
RTS PC
2$: TSTB OREG ;Console ready?
BNE 2$ ;Wait til it is
MOVB R0,OREG ;Output char
RTS PC
INCHR: TST OUTSW ;Where does it come from?
BEQ 1$
TSTB KBIS ;Anything typed on VT05?
BPL 2$ ; No
MOVB KBIR,R0 ; Read the char
RTS PC
1$: TSTB IREG ;Anything from the 10?
BEQ 2$ ; No
MOVB IREG,R0 ; Fetch the char
CLRB IREG
RTS PC
2$: CLR R0 ;No input
RTS PC
;Data & Constants
OBUF: .WORD 1,2,3,4,5,6,7,10 ;Message to send
.BLKW 20
IBUF: .BLKW 40 ;Where we'll store the message
OPTR: OBUF ;What to send next
OCNT: 10 ;How much left to send
IPTR: IBUF ;Where to store next word
ICNT: 10 ;How much left to receive
ADONE: .WORD 0 ;Set by DRINTA interrupt routine
BDONE: .WORD 0 ;Set by DRINTB interrupt routine
MDONE: .WORD 0 ;Set when message has been sent
BEGMES: .ASCII /πDR11-C Test Program/
CRLF: .BYTE 12,15,0
RAMES: .ASCIZ /πReady to generate an A interrupt/
RBMES: .ASCIZ /πReady to generate a B interrupt/
BIMES: .ASCIZ /πReady to generate both A & B interrupts/
NOIMES: .ASCIZ /π... but this shouldn't/
AMES: .ASCIZ /π - Handling an A request - /
BMES: .ASCIZ /π - Handling a B request - /
SNDMES: .ASCIZ /πSending a little message . . . /
RCVMES: .ASCIZ /πAll done now./
.END START
; DZ11.PAL
.INSRT STUFF.PAL[11,ARG]
;DZ11 definitions
DZCSR = 160000 ;Control and Status register
DZLPR = 160002 ;Line Parameter register (write only)
DZRBUF = 160002 ;Receiver Buffer register (read only)
DZTCR = 160004 ;Transmitter Control register (byte)
DZTBUF = 160006 ;Transmitter Buffer (byte, write only)
.=1000
START: RESET
MOV #START,SP ;Set up the stack
BIS #40,DZCSR ;Turn on master scan enable
ZERO: MOV #10,R0
MOV #LINE,R1
1$: CLR (R1)+
SOB R0,1$
TEST: MOV #1000,R0
2$: MOV DZRBUF,R1
SWAB R1
BIC #177770,R1
ASL R1
INC LINE(R1)
SOB R0,2$
FIN: BPT
BPT
LINE: .WORD 0,0,0,0,0,0,0,0
.END START
;Program to talk to one of the PUMA's with the VT05 PUMA.PAL
.INSRT STUFF.PAL[11,ARG]
;DZ11 definitions
DZCSR = 160000 ;Control and Status register
DZLPR = 160002 ;Line Parameter register (write only)
DZRBUF = 160002 ;Receiver Buffer register (read only)
DZTCR = 160004 ;Transmitter Control register (byte)
DZTBUF = 160006 ;Transmitter Buffer (byte, write only)
.=1000
START: RESET
MOV #START,SP ;Set up the stack
MOV #BEGMES,R1 ;Tell world who we are
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
;Set up the DZ11 using line # in LINE
MOV #13430,R0 ;line parameters: 1200 baud, 8 char, no parity
BIS LINE,R0 ;Choose which line
MOV R0,DZLPR ;Tell DZ11 what parameters to use
MOV #1,R0
ASH LINE,R0 ;Set up transmit bit for line we're using
MOVB R0,DZTCR ;Turn on transmit for line
BIS #40,DZCSR ;Turn on master scan enable
;Now talk
TLOOP: JSR PC,INCHR ;Any input - returned in R0
TST R0
BEQ 2$ ; No - go check if anything to print
CMP #3,R0 ;Was it a ↑C? (Do we really want this?)
BNE 1$ ; No
BPT ; Yes - break to DDT
BR 2$ ; Proceeding will just continue
1$: TST DZCSR ;Can we send it yet?
BPL 1$ ; No - wait til we can (This may not work)
MOVB R0,DZTBUF ;Send input char over
2$: MOV DZRBUF,R0 ;See if anything to output
BPL TLOOP ; No
JSR PC,OUTCHR ; Yes - print it
BR TLOOP ;Do it all again
;VT05 I/O routines
OUTSTR: MOVB (R1)+,R0 ;Get next char
BEQ 1$ ;If done - quit
JSR PC,OUTCHR ;Print it
BR OUTSTR
1$: JSR PC,OUTCHR ;Print a couple nulls
JSR PC,OUTCHR
; JMP OUTCHR
OUTCHR: TST OUTSW ;Who does it go to?
BEQ 2$
1$: TSTB KBOS ;VT05 ready?
BPL 1$ ;Loop til it is
MOVB R0,KBOR ;Print the char
RTS PC
2$: TSTB OREG ;Console ready?
BNE 2$ ;Wait til it is
MOVB R0,OREG ;Output char
RTS PC
INCHR: TST OUTSW ;Where does it come from?
BEQ 1$
TSTB KBIS ;Anything typed on VT05?
BPL 2$ ; No
MOVB KBIR,R0 ; Read the char
RTS PC
1$: TSTB IREG ;Anything from the 10?
BEQ 2$ ; No
MOVB IREG,R0 ; Fetch the char
CLRB IREG
RTS PC
2$: CLR R0 ;No input
RTS PC
;Data & Constants
LINE: .WORD 1 ;Which DZ11 line we are using
BEGMES: .ASCII /πPuma terminal program/
CRLF: .BYTE 12,15,0
.END START
;Program to test out communication with the Vision Module via the DR11-C
; VMTST.PAL
.INSRT STUFF.PAL[11,ARG]
; COMMANDS are:
TRANS= 040000 ; TRANSFER DATA COMMAND
ERESET= 140000 ; RESET
ERESAK= 160000 ; RESET ACKNOWLEDGE
; STATUS word values are:
; OK= 0 ; DONE WITH A CLR
ERBUF0= 101000 ; NO BUFFERS AVAILABLE FOR INPUT MESSAGE
ERBUFS= 102000 ; NEXT BUFFER IS TOO SMALL
ERCHKS= 103000 ; CHECKSUM ERROR
;DR11-C definitions
DRCSR = 763770 ;Control and Status register
DROBUF = 763772 ;Output Buffer register
DRIBUF = 763774 ;Input Buffer register
DRIVEC = 340 ;Request A & B interrupt vectors
.=DRIVEC
DRINTA ;Req A interrupt handler
240 ;Level 5
DRINTB ;Req B interrupt handler
240 ;Level 5
.=1000
START: RESET
MOV #START,SP ;Set up the stack
MOV #BEGMES,R1 ;Tell world who we are
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
CLR %PS ;Priority level 0
;Initialize the DR11-C link
MOV #DRINTA,DRIVEC ;Set up interrupt vectors
MOV #DRINTB,DRIVEC+4
CLR STATE ;We're not doing anything yet
MOV #140,DRCSR ;Enable interrupts
;See if anyone's home
MOV #6,STATE ;Send a RESET & see if it gets acknowledged
MOV #ERESET,DROBUF
INC DRCSR ;Int A in VM
MOV #100,R1 ;Now wait a while for the reset acknowledge
1$: CLR R0
2$: TST STATE
BEQ 3$ ;STATE will be set to 0 when we get the resak
SOB R0,2$
SOB R1,1$
MOV #TIMMES,R1 ;Time out
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT
BR START ;Try again
3$: BIS #2,DRCSR ;Set CSR 1 for "B" response (may not be needed)
;Mini test loop
TLOOP: MOV #RDYMES,R1 ;Ready to send a message over
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT
CLR CKSUM
MOV MESS,R0 ;R0 ← address of message to send
MOV (R0)+,R1 ;R1 ← Message length in bytes
MOV R1,R2
INC R2 ;In case odd number of bytes
ASR R2 ;Convert bytes → word count
MOV R2,SCNT ;Set up word count
MOV R0,SPTR ;Set up pointer at message
MOV #RBUF,RPTR ;Reset receive message pointer
BIS #TRANS,R1 ;R1 ← Send command bits + byte count
MOV R1,DROBUF ;Get ready to send it
BIC #3,DRCSR ;Clear CSR 0 & 1 bits
MOV #1,STATE
CLR SDONE
CLR RDONE
MOV #TSNMES,R1 ;Say we're trying to send it now
JSR PC,OUTSTR
INC DRCSR ;"A" Request for command
1$: TST SDONE ;Wait for it to have been sent
BEQ 1$
MOV #TRCMES,R1 ;Now we want to receive the VM's reply
JSR PC,OUTSTR
2$: TST RDONE ;Wait for it to have been received
BEQ 2$
MOV #DONMES,R1 ;Done - now we can look at the VM's reply
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BR TLOOP ;Ready to do it all again
;Interrupt routines
DRINTA: MOV R0,-(SP)
MOV #ADISP,R0 ;Use A dispatch table
BR DRINT
DRINTB: MOV R0,-(SP)
MOV #BDISP,R0 ;Use B dispatch table
DRINT: MOV R1,-(SP)
MOV R2,-(SP)
MOV R3,-(SP)
BIC #3,DRCSR ;Clear interrupt requests
MOV DRIBUF,R3 ;R3 ← Anything sent over to us
ADD STATE,R0
ADD STATE,R0 ;Get offset into dispatch table
JMP @0(R0) ;Go do it
INTRB: BIS #2,DRCSR ;Signal with a B request
INTRET: MOV (SP)+,R3
MOV (SP)+,R2
MOV (SP)+,R1
MOV (SP)+,R0
RTI
;Sending routines
; In case he's not ready to start receiving when we want to send
A1: BIC #777,R3 ;Clear all non-status bits
CLR STATE ;So we can receive
CMP #ERBUF0,R3 ;No buffers error?
BNE 2$
MOV #NBFMES,R1
1$: JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT
BR INTRB
2$: CMP #ERBUFS,R3 ;Buffer too small?
BNE 3$
MOV #SBFMES,R1
BR 1$
3$: CMP #ERESET,R3 ;External Reset?
BNE 4$
MOV #ERESAK,DROBUF ;Send a reset acknowledge
INC DRCSR ;Int A
MOV #RESMES,R1
BR 1$
4$: MOV #ERRMES,R1
BR 1$
;It's okay with him to send - ship it over
B1: INC STATE
MOV #SNDMES,R1 ;Say we're sending it now
JSR PC,OUTSTR
B2: DEC SCNT ;More to send?
BPL 1$ ; yes - do it
MOV CKSUM,DROBUF ; no - go send cksum
INC STATE ; Update state
BR INTRB ; B Req & return
1$: MOV @SPTR,R0 ;Fetch next word to send
XOR R0,CKSUM ;Update check sum
MOV R0,DROBUF ;Move it to output buffer
ADD #2,SPTR ;Bump pointer
BR INTRB ;B Req & return
;Done sending - see if he received it okay
A3: TST R3 ;Check status
BMI 1$ ; Error skip ahead
CLR STATE ;Done here
INC SDONE
BR INTRB ;B Req & return so VM can continue
1$: CMP #ERESET,R3 ;Remote Reset?
BNE 2$ ; no
MOV #ERESAK,DROBUF ;Send a reset acknowledge
INC DRCSR ;Int A
MOV #RESMES,R1
BR 3$
2$: MOV #CHKMES,R1 ;Must be a checksum error
3$: JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT
CLR CKSUM
MOV MESS,R0 ;R0 ← address of message to send
MOV (R0)+,R1 ;R1 ← Message length in bytes
MOV R1,R2
INC R2 ;In case odd number of bytes
ASR R2 ;Convert bytes → word count
MOV R2,SCNT ;Set up word count
MOV R0,SPTR ;Set up pointer at message
BIS #TRANS,R1 ;R1 ← Send command bits + byte count
MOV R1,DROBUF ;Get ready to send it
BIC #3,DRCSR ;Clear CSR 0 & 1 bits
MOV #1,STATE
CLR SDONE
CLR RDONE
MOV #RSDMES,R1 ;Say we're sending it now
JSR PC,OUTSTR
INC DRCSR ;"A" Request for command
BR INTRET ;Return from interrupt
;Receiving routines
;Ready to start receiving
A0: TST R3 ;See if transfer request
BGT 3$ ; yes - skip ahead & do it
BIC #17777,R3 ;Clear all except command bits
BNE 1$
JMP INTRB ;Null status - just ignore
1$: CMP #ERESET,R3 ;Make sure it was a reset
BNE 2$
MOV #ERESAK,DROBUF ;Send a reset acknowledge
INC DRCSR ;Int A & return
JMP INTRET
2$: MOV #ERRMES,R1 ;What's going on?
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT
MOV #ERESET,DROBUF ;Try to reset things
INC DRCSR
MOV #6,STATE ;Wait for reset acknowledgement
JMP INTRET
3$: BIC #TRANS,R3 ;Clear command bits
MOV R3,@RPTR ;Store byte count
ADD #2,RPTR
INC R3 ;In case odd number of bytes
ASR R3 ;Convert bytes to words
MOV R3,RCNT ;Store it
CLR CKSUM
MOV #4,STATE ;Receive data
MOV #RCVMES,R1 ;Say that we're receiving
JSR PC,OUTSTR
JMP INTRB ;B response & return
;Store the message away now
B4: DEC RCNT ;More to message?
BMI 1$ ; no - go get checksum
MOV R3,@RPTR ;Store data away
ADD #2,RPTR
XOR R3,CKSUM ;Accumulate checksum
JMP INTRB ;B response & return
1$: CMP R3,CKSUM ;Checksum okay
BNE 2$ ; No
INC STATE ; Yes - send ok status & wait til ok to proceed
CLR DROBUF
INC DRCSR ;A response & return
JMP INTRET
2$: MOV #CHKMES,R1 ;Checksum error
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
MOV #RRCMES,R1 ;Request retransmission
JSR PC,OUTSTR
CLR STATE
MOV #ERCHKS,DROBUF
INC DRCSR ;Req A
JMP INTRET
;Done receiving
B5: INC RDONE ;Let everyone know that we're done
CLR STATE
JMP INTRET
;Reset & bad requests
;Waiting for Reset Acknowledgement
A6: BIC #17777,R3 ;Strip to command bits
CMP #ERESET,R3 ;Check for VM reseting also
BNE 2$ ; no
MOV #ERESAK,DROBUF ; yes - acknowledge his
INC DRCSR ;Req A & return
1$: JMP INTRET
2$: CMP #ERESAK,R3 ;Is VM acknowledging us?
BNE 1$ ; no - ignore it
CLR STATE ; yes - ok
JMP INTRB ;B response & return
;Ignore Req B's
B0: JMP INTRET
;Bad Requests
ABAD: MOV #ABDMES,R1 ;Complain
BR BAD1
BBAD: MOV #BBDMES,R1 ;Complain
BAD1: JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
BPT
JMP INTRET
;VT05 I/O routines
OUTSTR: MOVB (R1)+,R0 ;Get next char
BEQ 1$ ;If done - quit
JSR PC,OUTCHR ;Print it
BR OUTSTR
1$: JSR PC,OUTCHR ;Print a couple nulls
JSR PC,OUTCHR
; JMP OUTCHR
OUTCHR: TST OUTSW ;Who does it go to?
BEQ 2$
1$: TSTB KBOS ;VT05 ready?
BPL 1$ ;Loop til it is
MOVB R0,KBOR ;Print the char
RTS PC
2$: TSTB OREG ;Console ready?
BNE 2$ ;Wait til it is
MOVB R0,OREG ;Output char
RTS PC
INCHR: TST OUTSW ;Where does it come from?
BEQ 1$
TSTB KBIS ;Anything typed on VT05?
BPL 2$ ; No
MOVB KBIR,R0 ; Read the char
RTS PC
1$: TSTB IREG ;Anything from the 10?
BEQ 2$ ; No
MOVB IREG,R0 ; Fetch the char
CLRB IREG
RTS PC
2$: CLR R0 ;No input
RTS PC
;Various Vision Module Messages
INIVIS: .WORD 4,0,0 ;Initialize communiations with Vision Module
RESTRT: .WORD 4,1,8. ;Soft Restart
PIC: .WORD 2,2 ;Take a picture
REPIC: .WORD 2,3 ;Reprocess the picture
GETFET: .WORD 6,4,1,8.,0,0,0,0
BLINK: .WORD 6,5,1,-1 ;Blink blob
DLBLOB: .WORD 4,6,1 ;Delete blob
CALIB: .WORD 4,7,1 ;Calibrate
REMEM: .WORD 12.,8.,7 ;Create a new prototype (#=7)
.ASCIZ /FOO/ ;Named FOO
.BLKW 10
RECOG: .WORD 4,10,1 ;Recognize blob
WHERE: .WORD 8.,11.,1,9.,0 ;Where are they all
SREAD: .WORD 11.,13. ;Read switch value
.ASCIZ /TRAINING/
.BLKW 10
SWRITE: .WORD 19.,14.,-1 ;Set switch (off)
.ASCIZ /KEEP-ALL-BLOBS/
.BLKW 10
VREAD: .WORD 24.,15. ;Read variable value
.ASCIZ /IMAGE-PROCESSING-TIME/
.BLKW 10
VWRITE: .WORD 23.,16. ;Write variable value
.FLT2 1.75
.ASCIZ /CALIBRATION-SIZE/
.BLKW 10
ERASE: .WORD 4,24.,0 ;Erase graphics overlay
CLEARW: .WORD 12.,25.,0,0,100,20,0 ;Clear an area
DRAW: .WORD 12.,26.,0,0,20,100,-1 ;Draw a vector
TEXT: .WORD 13.,27.,0,0 ;Display text
.ASCIZ /Hello?/
.BLKW 10
;Data & Constants
STATE: 0 ;What we're doing:
; 0 = nothing
; 1 = waiting for ok to start sending
; 2 = sending data & cksum
; 3 = waiting for message received ok
; 4 = receiving data & cksum
; 5 = waiting for ok to continue
; 6 = reset in progress
ADISP: .WORD A0,A1,ABAD,A3,ABAD,ABAD,A6 ;Req A dispatch table
BDISP: .WORD B0,B1,B2,BBAD,B4,B5,BBAD ;Req B dispatch table
SBUF: .BLKW 100 ;Message to send
RBUF: .BLKW 100 ;Where we'll store the message
MESS: SBUF ;Start of message to be sent
SPTR: SBUF ;What to send next
SCNT: 0 ;How much left to send
RPTR: RBUF ;Where to store next word
RCNT: 0 ;How much left to receive
CKSUM: 0
SDONE: .WORD 0 ;Set when message has been sent
RDONE: .WORD 0 ;Set when reply has been received
BEGMES: .ASCII /πVision Module Communication Test Program/
CRLF: .BYTE 12,15,0
RDYMES: .ASCIZ /πReady to send./
TSNMES: .ASCIZ /πTrying to Send . . ./
SNDMES: .ASCIZ /πSending . . . /
TRCMES: .ASCIZ /πReady to Receive . . ./
RCVMES: .ASCIZ /πReceiving . . ./
DONMES: .ASCIZ /πDone./
;Error messages
TIMMES: .ASCIZ /πTime out on reset acknowledge./
RESMES: .ASCIZ /πExternal reset./
NBFMES: .ASCIZ /πNo available buffers in VM./
SBFMES: .ASCIZ /πToo small buffer in VM./
ERRMES: .ASCIZ /πUnknown error./
RSDMES: .ASCIZ /πRe-Sending . . ./
RRCMES: .ASCIZ /πRequesting retransmission . . ./
CHKMES: .ASCIZ /πChecksum error./
ABDMES: .ASCIZ /πUnexpected A Request./
BBDMES: .ASCIZ /πUnexpected A Request./
.END START
;Program to talk to the 10 with the VT05
.INSRT STUFF.PAL[11,ARG]
;DZ11 definitions
DZCSR = 160000 ;Control and Status register
DZLPR = 160002 ;Line Parameter register (write only)
DZRBUF = 160002 ;Receiver Buffer register (read only)
DZTCR = 160004 ;Transmitter Control register (byte)
DZTBUF = 160006 ;Transmitter Buffer (byte, write only)
.=1000
START: RESET
MOV #START,SP ;Set up the stack
MOV #BEGMES,R1 ;Tell world who we are
JSR PC,OUTSTR
MOV #CRLF,R1
JSR PC,OUTSTR
;Set up the DZ11 for line #7
LP: MOV #13437,DZLPR ;line parameters: 1200 baud, 8 char, no parity
MOVB #200,DZTCR ;Turn on transmit for line 7
BIS #40,DZCSR ;Turn on master scan enable
;Now talk
TLOOP: JSR PC,INCHR ;Any input - returned in R0
TST R0
BEQ 2$ ; No - go check if anything to print
CMP #26,R0 ;Was it a ↑V? (Do we really want this?)
BNE 1$ ; No
BPT ; Yes - break to DDT
BR 2$ ; Proceeding will just continue
1$: TST DZCSR ;Can we send it yet?
BPL 1$ ; No - wait til we can (This may not work)
MOVB R0,DZTBUF ;Send input char over
2$: MOV DZRBUF,R0 ;See if anything to output
BPL TLOOP ; No
JSR PC,OUTCHR ; Yes - print it
BR TLOOP ;Do it all again
;VT05 I/O routines
OUTSTR: MOVB (R1)+,R0 ;Get next char
BEQ 1$ ;If done - quit
JSR PC,OUTCHR ;Print it
BR OUTSTR
1$: JSR PC,OUTCHR ;Print a couple nulls
JSR PC,OUTCHR
; JMP OUTCHR
OUTCHR: TST OUTSW ;Who does it go to?
BEQ 2$
1$: TSTB KBOS ;VT05 ready?
BPL 1$ ;Loop til it is
MOVB R0,KBOR ;Print the char
RTS PC
2$: TSTB OREG ;Console ready?
BNE 2$ ;Wait til it is
MOVB R0,OREG ;Output char
RTS PC
INCHR: TST OUTSW ;Where does it come from?
BEQ 1$
TSTB KBIS ;Anything typed on VT05?
BPL 2$ ; No
MOVB KBIR,R0 ; Read the char
RTS PC
1$: TSTB IREG ;Anything from the 10?
BEQ 2$ ; No
MOVB IREG,R0 ; Fetch the char
CLRB IREG
RTS PC
2$: CLR R0 ;No input
RTS PC
;Data & Constants
LINE: .WORD 0 ;Which DZ11 line we are using
BEGMES: .ASCII /π10 terminal program/
CRLF: .BYTE 12,15,0
.END START